package com.ptl.bp.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ptl.bp.entity.BatteryPassport;
import com.ptl.bp.dto.BatteryPassportQueryDTO;
import com.ptl.bp.dto.CountDTO;
import com.ptl.bp.mapper.BatteryPassportMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
@Service
public class BatteryPassportService extends ServiceImpl<BatteryPassportMapper, BatteryPassport> {


    @Transactional(rollbackFor = Exception.class)
    public Long createPassport(BatteryPassport passport) {
        // // 验证标识符唯一性
        // if (isIdentifierExist(passport.getBatteryPassportIdentifier())) {
        //     throw new IllegalArgumentException("电池护照标识符已存在");
        // }
        passport.setDocumentStatus(BatteryPassport.PassportDocumentStatus.DRAFT);
        // 设置创建时间
        passport.setCreateTime(LocalDateTime.now());
        passport.setUpdateTime(LocalDateTime.now());

        // 保存到数据库
        if (!save(passport)) {
            throw new RuntimeException("创建电池护照失败");
        }

        log.info("成功创建电池护照，ID: {}", passport.getId());
        return passport.getId();
    }


    public BatteryPassport getById(String id) {
        // 根据权限, 模糊数据 todo
        return baseMapper.selectById(id);
    }


    public IPage<BatteryPassport> pageQuery(Page<BatteryPassport> page, BatteryPassportQueryDTO queryDTO) {
        return baseMapper.pageQuery(page, queryDTO);
    }

    public List<CountDTO> countByPublishStatus() {
        return this.baseMapper.countByPublishStatus();
    }

    public List<CountDTO> countByMonth() {
        List<CountDTO> countDTOS = this.baseMapper.countByMonth();
        return completeMonths(countDTOS);
    }

    private List<CountDTO> completeMonths(List<CountDTO> originalData) {
        // 创建原始数据的映射
        Map<String, Long> originalMap = originalData.stream()
                .collect(Collectors.toMap(CountDTO::getName, CountDTO::getCount));

        // 生成最近12个月并补全数据
        return IntStream.range(0, 12)
                .mapToObj(i -> LocalDate.now().minusMonths(11 - i))
                .map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM")))
                .map(month -> new CountDTO(month, originalMap.getOrDefault(month, 0L)))
                .collect(Collectors.toList());
    }

    public List<CountDTO> countByYear() {
        List<CountDTO> countDTOS = this.baseMapper.countByYear();
        return completeYearsFromMin(countDTOS);
    }

    private List<CountDTO> completeYearsFromMin(List<CountDTO> originalData) {
        if (originalData.isEmpty()) {
            return Collections.emptyList();
        }

        // 找到最小年份和当前年份
        int minYear = originalData.stream()
                .mapToInt(dto -> Integer.parseInt(dto.getName()))
                .min()
                .orElse(LocalDate.now().getYear());

        int currentYear = LocalDate.now().getYear();

        // 创建年份映射
        Map<Integer, Long> yearMap = originalData.stream()
                .collect(Collectors.toMap(
                        dto -> Integer.parseInt(dto.getName()),
                        CountDTO::getCount
                ));

        // 从最小年份到当前年份补全
        return IntStream.rangeClosed(minYear, currentYear)
                .mapToObj(year -> new CountDTO(
                        String.valueOf(year),
                        yearMap.getOrDefault(year, 0L)
                ))
                .collect(Collectors.toList());
    }

    public List<CountDTO> countByManufacturer() {
        return this.baseMapper.countByManufacturer();
    }

    public List<CountDTO> countByModel() {
        return this.baseMapper.countByModel();
    }
}
